package com.fsy.its.service;

import com.alibaba.fastjson.JSON;
import com.fsy.common.mqtt.MqttGateway;
import com.fsy.its.dao.AlarmMapper;
import com.fsy.its.dao.BuildingMapper;
import com.fsy.its.dao.ParkMapper;
import com.fsy.its.dao.PointInfoMapper;
import com.fsy.its.entity.*;
import com.fsy.its.netty.msg.FireStateMsg;
import com.fsy.its.util.Const;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.util.Map;

@Service
@Slf4j
public class AlarmService {

    @Autowired
    private AlarmMapper alarmMapper;

    @Autowired
    private PointInfoMapper pointInfoMapper;

    @Autowired
    private BuildingMapper buildingMapper;

    @Autowired
    private ParkMapper parkMapper;

    @Autowired
    private MqttGateway mqttGateway;

    @Async("asyncMsgExecutor")
    public void doAlarm(Dtu dtu, FireStateMsg fireStateMsg) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        PointInfo pointInfo = pointInfoMapper.getByPointNumber(dtu.getBuildingId(), fireStateMsg.component.addr);
        if( pointInfo == null ) {
            log.error("Point information not found, buildingId={}, componentAddr={}",
                    dtu.getBuildingId(), fireStateMsg.component.addr);
            return;
        }
        Alarm alarm = new Alarm();
        alarm.setAlertTime(fireStateMsg.head.time);
        alarm.setCreateTime(LocalDateTime.now());
        alarm.setDescription(fireStateMsg.component.desc);
        alarm.setPointId(pointInfo.getId());
        alarm.setTransType(Const.TRANS_TYPE_DTU);
        alarm.setTransId(dtu.getId());
        alarm.setState(Const.ALARM_STATE_OCCURRED);

        StringBuilder topic = new StringBuilder();
        if( fireStateMsg.getAlarm() == 1 ) {
            alarm.setType(Const.ALARM_TYPE_FIRE);
            alarmMapper.insert(alarm);
            topic.append(Const.TOPIC_FIRE);
        }
        if( fireStateMsg.getFault() == 1) {
            alarm.setType(Const.ALARM_TYPE_FAULT);
            alarmMapper.insert(alarm);
            topic.append(Const.TOPIC_FAULT);
        }

        Building building = buildingMapper.selectById(dtu.getBuildingId());
        Park park = parkMapper.selectById(building.getParkId());
        Map<String, String> alarmInfo = BeanUtils.describe(alarm);
        alarmInfo.put("parkId", Integer.toString(park.getId()));
        alarmInfo.put("parkName", park.getName());
        alarmInfo.put("buildingId", Integer.toString(building.getId()));
        alarmInfo.put("buildingName", building.getName());
        alarmInfo.put("floor", pointInfo.getFloor());
        alarmInfo.put("room", pointInfo.getRoom());
        alarmInfo.put("pointNumber", pointInfo.getPointNumber());
        alarmInfo.put("pointDesc", pointInfo.getPointDesc());

        //长度为6的行政区编码
        topic.append(String.valueOf(park.getAreaCode()), 0, 6);
        //园区和建筑物id
        topic.append("/").append(park.getId());
        topic.append("/").append(building.getId());

        //发消息到mqtt
        mqttGateway.sendToMqtt(JSON.toJSONString(alarmInfo), topic.toString());
    }
}
